/*
  Copyright (c) 2010
  The Regents of the University of Michigan
  All Rights Reserved

  Permission is granted to use, copy, create derivative works, and
  redistribute this software and such derivative works for any purpose,
  so long as the name of the University of Michigan is not used in
  any advertising or publicity pertaining to the use or distribution
  of this software without specific, written prior authorization. If
  the above copyright notice or any other identification of the
  University of Michigan is included in any copy of any portion of
  this software, then the disclaimer below must also be included.

  This software is provided as is, without representation or warranty
  of any kind either express or implied, including without limitation
  the implied warranties of merchantability, fitness for a particular
  purpose, or noninfringement.  The Regents of the University of
  Michigan shall not be liable for any damages, including special,
  indirect, incidental, or consequential damages, with respect to any
  claim arising out of or in connection with the use of the software,
  even if it has been or is hereafter advised of the possibility of
  such damages.
*/
#ifndef LOOKUP_H
#define LOOKUP_H

#define LOOKUP_CONCURRENCY 5
#define LOOKUP_K 20
#define MAX_RETRIES 1

struct ClearviewInstance;
struct Lookup;
struct ReplyFindNodePacket;

struct PendingFindNode {
  struct ContactAddress *contact;
  struct Lookup *parent;  // Don't touch outside clearview_new.
  struct event *timeout;
  int tries_left;
};


struct Lookup *lookup_new(void);
void lookup_free(struct Lookup *victim);
struct Lookup *lookup_copy(struct Lookup *rhs);

void lookup_start(struct ClearviewInstance *cv, struct Lookup *lookup,
                  char *id);

// Return nonzero if the lookup is finished, zero otherwise.
int lookup_is_done(struct Lookup *lookup);

// Return nonzero if the current lookup should continue.
// Return zero otherwise (i.e., there is no current lookup, or there
// is one and it should stop, or it ran out of contacts to query and cannot
// continue.)
int lookup_should_continue(struct Lookup *lookup);

int lookup_send_query(struct Lookup *lookup);

void lookup_cleanup(struct Lookup *lookup);

void remove_pending_find(struct Lookup *lookup,
                         struct PendingFindNode *victim);

void free_pending_find(struct PendingFindNode *victim);


// Notify the lookup about an incoming find-node. Currently responsible
// for freeing the data in the reply.
void lookup_handle_find_reply(struct Lookup *lookup,
                              struct ReplyFindNodePacket *reply,
                              struct ContactAddress *contact);
#endif /* LOOKUP_H */
